package com.ebelter.btcomlib.models.bluetooth.products.scale;

import android.os.Handler;
import android.os.Looper;


import com.ebelter.btcomlib.models.beans.ScaleUser;
import com.ebelter.btcomlib.models.bluetooth.products.scale.bean.ScaleFatResult;
import com.ebelter.btcomlib.models.bluetooth.products.scale.bean.ScaleMeasureResult;
import com.ebelter.btcomlib.models.bluetooth.products.scale.bean.ScaleMeasureResultAnalyzer;
import com.ebelter.btcomlib.models.bluetooth.products.scale.interfaces.IScaleMeasureCallback;
import com.ebelter.btcomlib.models.eventbus.CommonEventBus;
import com.ebelter.btcomlib.utils.BytesUtils;
import com.ebelter.btcomlib.utils.TimeUtils;
import com.ebelter.btcomlib.utils.log.LogUtils;

import org.greenrobot.eventbus.EventBus;

import java.util.Calendar;

/**
 * byte解析工具类
 */
public class ScaleBytesAnalysisFatory {


    private static final String TAG="ScaleBytesAnalysis";

    private Handler myMainHandler;

    public ScaleBytesAnalysisFatory() {
        this.myMainHandler = new Handler(Looper.getMainLooper());
    }


    private IScaleMeasureCallback mIScaleMeasureCallback;

    public void setmIMeasureResultCallback(IScaleMeasureCallback IScaleMeasureCallback) {
        this.mIScaleMeasureCallback = IScaleMeasureCallback;
    }


    private ScaleOtaUpdate mScaleOtaUpdate;//ota的升级工具类


    //protected StringBuilder dataSb;

    private void sendLog2(String msg){
        CommonEventBus eventBus=new CommonEventBus(TAG,"CeshiActivity",22,msg);
        EventBus.getDefault().post(eventBus);
    }

    public void resultAnalysis(final byte[] data){

        LogUtils.i(TAG,"ScaleBytesAnalysisFatory-解析的元数据="+ BytesUtils.bytes2HexStr(data));

        if (data==null||data.length<=3){
            LogUtils.i(TAG,"ScaleBytesAnalysisFatory-不能处理错误数据");
            return;
        }

        //验证包头
        if (data[0]!=(byte) 0x8d){
            LogUtils.i(TAG,"ScaleBytesAnalysisFatory-数据包头不正确");
            return;
        }
        //验证数据长度
        if (data.length != (data[1] & 0xff) + 3){
            LogUtils.i(TAG,"ScaleBytesAnalysisFatory-数据长度不正确");
            return;
        }
        LogUtils.i(TAG,"ScaleBytesAnalysisFatory-解析的数据="+ BytesUtils.bytes2HexStr(data));

        //sendLog2("ScaleBytesAnalysisFatory-解析的数据="+ BytesUtils.bytes2HexStr(data));


        int cmdCode = data[2] & 0xff;
        LogUtils.i(TAG,"ScaleBytesAnalysisFatory-cmd = "+cmdCode);

        switch (cmdCode) {
            case 0x00:
                break;
            case 0x90: //秤已唤醒
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-秤已唤醒");
                myMainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mIScaleMeasureCallback!=null)mIScaleMeasureCallback.onScaleWake();
                    }
                });
                break;
            case 0x91: //秤已休眠
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-秤已休眠");
                myMainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mIScaleMeasureCallback!=null)mIScaleMeasureCallback.onScaleSleep();
                    }
                });
                break;
            case 0x92:        //称重单位已经改变
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-称重单位已经改变");
                onScaleUnitChanged(data);
                break;
            case 0x93:  //接收到第n组闹钟
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-接收到第n组闹钟");
                break;
            case 0x98: //接收到当前时钟
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-接收到当前时钟");
                onReceiveTime(data);
                break;
            case 0x9c: //接收到版本信息
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-接收到版本信息");
                onReceiveScaleVersion(data);
                break;
            case 0x9e: //接收到体脂肪测量结果
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-接收到体脂肪测量结果");
                onReceiveMeasureResult(data);
                break;
            case 0xa0: //接收到历史测量数据
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-接收到历史测量数据");
                onReceiveHistoryMeasureResult(data);
                break;
            case 0xa1:    //接收到升级包应答
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-接收到升级包应答");
                onUpgradeResponse(data);
                break;
            case 0xa2:    //升级结果
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-升级结果");
                onUpgradeResult(data);
                break;
            case 0xa3:    //体重数据
                break;
            case 0xa4:    //低电提示
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-低电提示");
                onScaleLowPower(data);
                break;
            case 0xa5:    //测脂出错
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-测脂出错");
                myMainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mIScaleMeasureCallback!=null) mIScaleMeasureCallback.onFatMeasureError(data[3] & 0xff);
                    }
                });

                break;
            case 0xa6:    //接收到修改闹钟ACK
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-接收到修改闹钟ACK");

//                expectAck = EnumAck.ACK_SET_ALARM;
//                ((IWeightMessageCallBack) msgCallBack).onSetClockAck();
                break;
            case 0xa7:    //接收到OTA升级就绪消息
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-接收到OTA升级就绪消息");
                onOtaUpgradeReady(data);
                break;
            case 0xa8:    //接收到用户列表标记值响应

                break;
            case 0xa9:    //秤历史记录上传完毕消息
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-秤历史记录上传完毕消息");
                onHistoryDownloadDone(data);
                break;
            case 0xaa:    //王工 ota升级
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-scaleOtaResponse 升级 "+BytesUtils.bytes2HexStr(data));
                scaleOtaResponse(data);
                break;

            case 0xb0: //秤响应app的列表更新指令
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-用户信息设置成功");
                onUserInfoSettingSucceeded();
                break;

            case 0xb1://秤响应无连接前测量结果响应
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-秤响应无连接前测量结果响应");
                break;
            case 0xb6: //上传秤是否与手机绑定过
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-上传秤是否与手机绑定过");

                break;
            case 0xb7:  //绑定确认指令
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-绑定确认指令");
                break;
            case 0xb8:                //OTA sha256校验码下发响应
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-OTA sha256校验码下发响应 case 0xb8");
                int no=1;
                if (data[3] == 1) {
                    no=1;
                } else {
                    no=2;
                }
                if (mScaleOtaUpdate!=null){
                    mScaleOtaUpdate.mIOtaUpdateCallback.onReceiveSha256Pkg(no);
                }
                break;

            case 40:
                LogUtils.i(TAG,"ScaleBytesAnalysisFatory-OTA sha256校验码下发响应  case 40");
                int no2=1;
                if (data[3] == 1) {
                    no2=1;
                } else {
                    no2=2;
                }
                if (mScaleOtaUpdate!=null){
                    mScaleOtaUpdate.mIOtaUpdateCallback.onReceiveSha256Pkg(no2);
                }
                break;


        }



    }

    private void scaleOtaResponse(byte[] data) {
        if (mIScaleMeasureCallback != null) {
            if (data.length==5){
                mIScaleMeasureCallback.dealScaleResponse(data[3],0);
            }else if (data.length==7){
                int p = BytesUtils.getIntFrom2Byte(data[5],data[4]);
                mIScaleMeasureCallback.dealScaleResponse(data[3],p);
            }
        }

    }


    private long lastMeasureTime;
    private void onReceiveMeasureResult(byte[] data) {
        ScaleFatResult fatResultBean = getFatResult(data);
        if (fatResultBean == null) {
            return;
        }
        final ScaleMeasureResult result = ScaleMeasureResultAnalyzer.getInstance().getMeasureResult(fatResultBean, ScaleUser.getUser());

        if ("0-00-00 00:00:00".equals(result.measureTime)){
            LogUtils.i(TAG,"----接收到了动态测量数据："+result);
            myMainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mIScaleMeasureCallback != null) {
                        mIScaleMeasureCallback.onReceivedynamicMeasureResult(result);
                    }
                }
            });
            return;
        }


        LogUtils.i2(TAG,"----result="+result);



        long time = TimeUtils.parseFormatter1Time(result.getMeasureTime()).getTime();
        if (time-lastMeasureTime <= 6000){
            LogUtils.i2(TAG,"测量时间太近 被屏蔽掉 lastMeasureTime="+TimeUtils.formatTime1(lastMeasureTime)+"--这次time="+TimeUtils.formatTime1(time));
            return;
        }
        lastMeasureTime=time;


        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mIScaleMeasureCallback != null) {

                    if (result.mesureCode==-1){
                        mIScaleMeasureCallback.onFatMeasureError(0);
                    }
                    mIScaleMeasureCallback.onReceiveMeasureResult(result);

                }
            }
        });
    }



    /**
     * 接收版本信息
     */
    private void onReceiveScaleVersion(byte[] data) {
        //ble固件
        int ble0 = data[3] & 0xff;
        int ble1 = data[4] & 0xff;
        //秤固件
        int scale0 = data[5] & 0xff;
        int scale1 = data[6] & 0xff;
        //系数固件
        int coefficient0 = data[7] & 0xff;
        int coefficient1 = data[8] & 0xff;
        //算法固件
        int arithmetic0 = data[9] & 0xff;
        int arithmetic1 = data[10] & 0xff;

        final int bleVer = (ble1 << 8) | ble0;
        final int scaleVer = (scale1 << 8) | scale0;
        final int coefficientVer = (coefficient1 << 8) | coefficient0;
        final int arithmeticVer = (arithmetic1 << 8) | arithmetic0;
        LogUtils.i(TAG, "receive scale version info." +
                "bleVer:" + bleVer +
                "scaleVer:" + scaleVer +
                "coefficientVer:" + coefficientVer +
                "arithmeticVer:" + arithmeticVer);


        //接收版本信息回调


        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if(mScaleOtaUpdate!=null){
                    mScaleOtaUpdate.mIOtaUpdateCallback.onGotScaleVersion(bleVer, scaleVer, coefficientVer, arithmeticVer);
                }
            }
        });

    }

    /**
     * 高8位低8位拼接
     * @param high 高8位字节
     * @param low  低8位字节
     */
    private int get2ByteValue(byte high, byte low) {
        return ((high & 0xff) << 8) | (low & 0xff);
    }

    //称重单位已经改变
    private void onScaleUnitChanged(byte[] data) {
        final String scaleUnit = data[3] == 1 ? ScaleMeasureResultAnalyzer.kg : ScaleMeasureResultAnalyzer.lb;
        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mIScaleMeasureCallback != null) {
                    mIScaleMeasureCallback.unitChange(scaleUnit);
                }
            }
        });

    }

    private ScaleFatResult getFatResult(byte[] data) {
        if (data == null || data.length < 18) {
            return null;
        }
        int userId = data[3] & 0xff;

        float weight = get2ByteValue(data[5], data[4]) / 10.0f;
        float fat = get2ByteValue(data[7], data[6]) / 10.0f;

        //时间
        int year = get2ByteValue(data[9], data[8]);
        int month = data[10] & 0xff;
        int day = data[11] & 0xff;
        int hour = data[12] & 0xff;
        int minute = data[13] & 0xff;
        int second = data[14] & 0xff;
        int weekOfYear = data[15] & 0xff;
        //"testDate":"2018-03-15 12:11:12"

        //电阻
        int resistance = get2ByteValue(data[17], data[16]);

        ScaleFatResult fatResultBean = new ScaleFatResult();
        fatResultBean.setUserId(userId);
        fatResultBean.setYear(year);
        fatResultBean.setMonth(month);
        fatResultBean.setDay(day);
        fatResultBean.setHour(hour);
        fatResultBean.setMinute(minute);
        fatResultBean.setSecond(second);
        fatResultBean.setWeekOfYear(weekOfYear);
        fatResultBean.setResistance(resistance);
        fatResultBean.setWeight(weight);
        fatResultBean.setFat(fat);
        boolean isUnitKg;
        int unitByte= (data[18] & 0xff);
        isUnitKg = 0x01 != unitByte;//判断传过来的单位类型
        fatResultBean.setUnitIsKG(isUnitKg);
        return fatResultBean;
    }

    /**
     * 接收到历史测量数据
     */
    private void onReceiveHistoryMeasureResult(byte[] data) {
        ScaleFatResult fatResultBean = getFatResult(data);
        if (fatResultBean == null) {
            return;
        }
        //是否疑似数据
        int suspectedData = data[18];
        //是否疑似数据
        fatResultBean.setSuspectedData((suspectedData & 0xff) == 170);
        LogUtils.i(TAG, "receive history data : " + fatResultBean.toString());
        final ScaleMeasureResult result = ScaleMeasureResultAnalyzer.getInstance().getOfflineMeasureResult(fatResultBean, ScaleUser.getUser());

        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mIScaleMeasureCallback != null) {
                    mIScaleMeasureCallback.onReceiveHistoryRecord(result);
                }
            }
        });
    }

    /**
     * 升级应答
     */
    private void onUpgradeResponse(final byte[] data) {


        int pkg1 = data[3] & 0xff;
        int pkg2 = data[4] & 0xff;
        final int pkg = (pkg2 << 8) | pkg1;

        LogUtils.i(TAG,"接收到升级包应答 pkg="+pkg+"----data = "+BytesUtils.bytes2HexStr(data));


        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mScaleOtaUpdate != null) {

                    LogUtils.i(TAG,"接收到升级包应答 onUpgradeResponse--data[5]="+data[5]);



                    mScaleOtaUpdate.mIOtaUpdateCallback.onUpgradeResponse(pkg, (data[5] & 0xff) == 0);

                }
            }
        });
    }

    /**
     *  升级结果
     */
    private void onUpgradeResult(final byte[] data) {
        final int result = data[3] & 0xff;
        final int type = data[4] & 0xff;
        LogUtils.i(TAG, "--接收到升级结果 result:" + result+"   type = "+type);

        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mScaleOtaUpdate != null) {
                    mScaleOtaUpdate.mIOtaUpdateCallback.onUpgradeResult(result, type);
                }
            }
        });
    }

    /**
     * 低电提醒
     */
    private void onScaleLowPower(byte[] data){
        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if(mIScaleMeasureCallback != null){
                    mIScaleMeasureCallback.onLowPower();
                }
            }
        });
    }

    /**
     * 固件升级就绪
     */
    private void onOtaUpgradeReady(final byte[] data){
        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if(mScaleOtaUpdate!=null){
                         // data[3]  00：可以升级  01：不可升级（电量低）
                    mScaleOtaUpdate.mIOtaUpdateCallback.onOtaUpgradeReady(data[3]);
                }
            }
        });
    }

    /**
     * 获取历史数据完成
     */
    private void onHistoryDownloadDone(byte[] data){
        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if(mIScaleMeasureCallback!=null){
                    mIScaleMeasureCallback.onHistoryDownloadDone();
                }
            }
        });
    }

    /**
     * 用户信息设置成功
     */
    private void onUserInfoSettingSucceeded() {
        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if(mIScaleMeasureCallback!=null){
                    mIScaleMeasureCallback.setUserInfoSuccess();
                }
            }
        });
    }

    /**
     * 接收当前时间
     */
    private void onReceiveTime(byte[] data) {
        LogUtils.i(TAG, "----onReceiveAlarmClock---receive scale clock.");
        int year = get2ByteValue(data[4], data[3]);
        int month = data[5] & 0xff;
        int day = data[6] & 0xff;
        int hour = data[7] & 0xff;
        int minute = data[8] & 0xff;
        int second = data[9] & 0xff;
        int weekOfYear = data[10] & 0xff;

        LogUtils.i(TAG, "got scale curr clock info." +
                "year:" + year +
                "month:" + month +
                "day:" + day +
                "hour:" + hour +
                "minute:" + minute +
                "second:" + second +
                "weekOfYear:" + weekOfYear);

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DATE, day);
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, minute);
        cal.set(Calendar.SECOND, second);
        final long scaleDateLong = cal.getTime().getTime();
        myMainHandler.post(new Runnable() {
            @Override
            public void run() {
                if(mIScaleMeasureCallback!=null){
                    mIScaleMeasureCallback.receiveTime(scaleDateLong);
                }
            }
        });

    }


    public void setScaleOtaUpdate(ScaleOtaUpdate scaleOtaUpdate) {
        this.mScaleOtaUpdate = scaleOtaUpdate;
    }
}
